package com.xci.xajtfb.bus.service;

import com.github.lvyanyang.core.PageList;
import com.xci.xajtfb.bus._core.BusBaseService;
import com.xci.xajtfb.bus.dao.StationInfoDao;
import com.xci.xajtfb.bus.dao.TbPassStationDao;
import com.xci.xajtfb.bus.entity.*;
import com.xci.xajtfb.bus.filter.StationFilter;
import com.xci.xajtfb.bus.filter.TbPassStationFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 站点 服务
 * @author 张谦 765870682@qq.com
 * @since 2021-03-11 9:50:00
 */
@Slf4j
@Service
public class StationInfoService extends BusBaseService {
    /**
     * 站点 数据层
     */
    @Resource
    private StationInfoDao stationInfoDao;

    /**
     * 存储管理线路途经站点数据 数据层
     */
    @Resource
    private TbPassStationDao synTbPassStationDao;

    public static double DEGREES_TO_RADIANS = Math.PI / 180.0;
    public static double RADIANS_TO_DEGREES = 180.0 / Math.PI;
    //地球半径
    public static double EARTH_MEAN_RADIUS_KM = 6371.009;
    //地球直径
    private static double EARTH_MEAN_DIAMETER = EARTH_MEAN_RADIUS_KM * 2;

    /**
     * 查询 站点 列表
     * @param stationName 站点名称
     * @param longitude 经度
     * @param latitude 纬度
     * @return 返回符合条件的数据集合
     */
    public List<StationInfo> selectList(String stationName,String longitude, String latitude) {
        StationFilter stationFilter =new StationFilter();
        stationFilter.setStationName(stationName);
        List<StationInfo> originList = stationInfoDao.selectList(stationFilter);
        //根据当前 精度 纬度 算出所有站点的距离
        List<StationInfo> stations = computerUserDistance(originList,longitude, latitude,"10000000");
        return stations;
    }

    /**
     * 查询 站点 分页列表
     * @param filter 过滤条件
     * @return 返回符合条件的分页数据集合
     */
    public PageList<StationInfo> selectPageList(StationFilter filter) {
        return PageList.of(stationInfoDao.selectPageList(filter));
    }

    /**
     * 通过坐标信息查询公交站点信息
     * @param longitude 经度
     * @param latitude 纬度
     * @param distance 距离
     * @return
     */
    public List<StationInfo> getStationByLonglat(String longitude, String latitude, String distance){
        StationFilter stationFilter =new StationFilter();
        List<StationInfo> originList = stationInfoDao.selectList(stationFilter);
        //根据当前 精度 纬度 算出所有站点的距离
        List<StationInfo> stations = computerUserDistance(originList,longitude, latitude,distance);
        return stations;
    }

    /***
     * 根据当前 经度维度 算出和站点的距离
     * @param stationInfoList  List<StationInfo>需要计算的数据
     * @param longitude  纬度（当前）
     * @param latitude 经度（当前）
     * @param distance 距离
     * @return
     */
    public List<StationInfo> computerUserDistance(List<StationInfo> stationInfoList,String longitude, String latitude, String distance){
        //根据当前精度 维度 -》要stationInfoList 算出 和当前距离
        List<StationInfo> targetList = new ArrayList<StationInfo>();
        for (StationInfo item : stationInfoList){
            StationInfo entity = new StationInfo();
            entity.setStationId(item.getStationId());
            entity.setStationName(item.getStationName());
            entity.setLocation(item.getLocation());
            entity.setLongitude(item.getLongitude());
            entity.setLatitude(item.getLatitude());
            entity.setDistance(twoLonLatDistance(Double.parseDouble(item.getLatitude()),
                    Double.parseDouble(item.getLongitude()), Double.parseDouble(latitude), Double.parseDouble(longitude)));
            targetList.add(entity);
        }
        //根据要显示的具体--》过滤出显示的数据
        Double newdistance = Double.parseDouble(distance) / 1000;
        //根据 距离 过滤出 附近的站点
        List<StationInfo> targetStationList = targetList.stream()
                .filter(stationInfo -> stationInfo.getDistance() <= newdistance)
                .collect(Collectors.toList());
        for (StationInfo item : targetStationList) {
            TbPassStationFilter synTbPassStationFilter = new TbPassStationFilter();
            synTbPassStationFilter.setStationId(item.getStationId().toString());
            List<TbPassStation> synTbPassStationList = synTbPassStationDao.selectList(synTbPassStationFilter);
            item.setTbPassStationList(synTbPassStationList);
        }
        return targetStationList;
    }

    /**
     * 两坐标[经纬度]之间的距离
     * @param lat1  经度1
     * @param lon1  纬度1
     * @param lat2  经度2
     * @param lon2  纬度2
     * @return
     */
    public static Double twoLonLatDistance(Double lat1, Double lon1, Double lat2, Double lon2){
        //计算经纬度
        Double latRad = lat2 * DEGREES_TO_RADIANS;
        Double lonRad = lon2 * DEGREES_TO_RADIANS;
        //计算经纬度的差
        double diffX = lat1 * DEGREES_TO_RADIANS - latRad;
        double diffY = lon1 * DEGREES_TO_RADIANS - lonRad;
        //计算正弦和余弦
        double hsinX = Math.sin(diffX * 0.5);
        double hsinY = Math.sin(diffY * 0.5);
        double latCenterRad_cos = Math.cos(lat1 * DEGREES_TO_RADIANS);
        double h = hsinX * hsinX + (latCenterRad_cos * Math.cos(latRad) * hsinY * hsinY);

        return (EARTH_MEAN_DIAMETER * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h)));
    }
}
